package controllers

import (
	"go-gin-demo/dao/mysql"
	"go-gin-demo/models"
	"go-gin-demo/service"
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"go.uber.org/zap"
)

// SignUpHandler 注册处理
func SignUpHandler(c *gin.Context) {
	// 参数校验
	p := new(models.ParamSignUp)
	if err := c.ShouldBindJSON(p); err != nil {
		zap.L().Error("SignUp with invalid param", zap.Error(err))
		errs, ok := err.(validator.ValidationErrors)
		if !ok {
			ResponseError(c, CodeInvalidParam)
			return
		}
		ResponseErrorWithMsg(c, CodeInvalidParam, removeTopStruct(errs.Translate(trans)))
		return
	}

	// 业务处理
	if err := service.SignUp(p); err != nil {
		zap.L().Error("service.SignUp failed", zap.Error(err))
		if errors.Is(err, mysql.ErrorUserExist) {
			ResponseError(c, CodeUserExist)
			return
		}
		ResponseError(c, CodeServerBusy)
		return
	}

	// 返回响应
	ResponseSuccess(c, nil)
}

// LoginHandler 登录处理
func LoginHandler(c *gin.Context) {
	// 获取请求参数以及校验
	p := new(models.ParamLogin)
	if err := c.ShouldBindJSON(p); err != nil {
		zap.L().Error("Login with invalid param", zap.Error(err))
		errs, ok := err.(validator.ValidationErrors)
		if !ok {
			ResponseError(c, CodeInvalidParam)
			return
		}
		ResponseErrorWithMsg(c, CodeInvalidParam, removeTopStruct(errs.Translate(trans)))
		return
	}
	// 业务逻辑处理
	aToken, rToken, err := service.Login(p)
	if err != nil {
		zap.L().Error("service.Login failed", zap.String("username", p.Username))
		if errors.Is(err, mysql.ErrorUserExist) {
			ResponseError(c, CodeUserNotExist)
		}
		ResponseError(c, CodeInvalidPasswd)
		return
	}
	token := gin.H{
		"a_token": aToken,
		"r_token": rToken,
	}
	// 返回响应
	ResponseSuccess(c, token)
}

// RefreshTokenHandler 刷新 token 处理
func RefreshTokenHandler(c *gin.Context) {
	// 获取请求参数以及校验
	p := new(models.ParamRefreshToken)
	if err := c.ShouldBindJSON(p); err != nil {
		zap.L().Error("RefreshToken with invalid param", zap.Error(err))
		errs, ok := err.(validator.ValidationErrors)
		if !ok {
			ResponseError(c, CodeInvalidParam)
			return
		}
		ResponseErrorWithMsg(c, CodeInvalidParam, removeTopStruct(errs.Translate(trans)))
		return
	}
	// 业务逻辑处理
	aToken, err := service.RefreshToken(p)
	if err != nil {
		zap.L().Error("service.RefreshToken failed", zap.String("a_token", p.AToken), zap.String("r_token", p.RToken))
		ResponseError(c, CodeInvalidToken)
		return
	}
	// 返回响应
	ResponseSuccess(c, aToken)
}
